Aller au contenu principal

Architecture et configuration de l’application

1) Les trois niveaux d’app Flutter

Flutter propose trois niveaux principaux :

  1. WidgetsApp (niveau bas, minimal)
  2. MaterialApp (design Material)
  3. CupertinoApp (design iOS)

WidgetsApp (bas niveau)

WidgetsApp fournit la gestion de base (routing, focus, localisation), mais aucun style par défaut.

import 'package:flutter/widgets.dart';

void main() {
runApp(const MinimalApp());
}

class MinimalApp extends StatelessWidget {
const MinimalApp({super.key});


Widget build(BuildContext context) {
return WidgetsApp(
color: const Color(0xFF2196F3),
builder: (context, child) {
return const Directionality(
textDirection: TextDirection.ltr,
child: Center(child: Text('App minimale (WidgetsApp)')),
);
},
);
}
}

N'utiliser une WidgetsApp seulement si vous voulez tout contrôler vous‑même.

Contrôles disponibles avec WidgetsApp

Widgets de base (sans style Material) :

  • Conteneurs : Container, SizedBox, Padding, Row, Column, Stack, Expanded, Wrap
  • Texte : Text, RichText, DefaultTextStyle
  • Entrées : TextField, EditableText
  • Listes : ListView, GridView, SingleChildScrollView
  • Navigation : Navigator, Route
  • Gestion d'état : StatefulWidget, StatelessWidget, InheritedWidget
  • Images : Image, AssetImage, NetworkImage
  • Gestes : GestureDetector, InkWell
  • Boîtes de dialogue : showDialog, AlertDialog (non-stylisé)
  • Média : Video, Audio (via plugins)

Tous les contrôles sont "bruts" sans design prédéfini. Vous devez styliser manuellement avec Container, TextStyle, etc.

MaterialApp (Android / Design Material)

import 'package:flutter/material.dart';

void main() {
runApp(const MyApp());
}

class MyApp extends StatelessWidget {
const MyApp({super.key});


Widget build(BuildContext context) {
return MaterialApp(
title: 'Material App',
theme: ThemeData(
useMaterial3: true,
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
),
home: const HomeScreen(),
);
}
}

class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});


Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Accueil')),
body: Center(
child: ElevatedButton(
onPressed: () {},
child: const Text('Bouton Material'),
),
),
);
}
}

Contrôles disponibles avec MaterialApp

Widgets Material Design :

  • Layout : Scaffold, AppBar, FloatingActionButton, BottomAppBar, BottomNavigationBar, BottomSheet, Drawer, TabBar, TabBarView
  • Boutons : ElevatedButton, TextButton, OutlinedButton, IconButton, FloatingActionButton, PopupMenuButton
  • Entrées : TextField, TextFormField, Checkbox, Radio, Switch, Slider, DatePicker, TimePicker
  • Listes : ListView, GridView, ListTile, Card, ExpansionTile, DataTable
  • Boîtes de dialogue : AlertDialog, SimpleDialog, SnackBar, showDialog, showModalBottomSheet
  • Indicateurs : CircularProgressIndicator, LinearProgressIndicator, Tooltip
  • Cartes : Card
  • Pages : PageView, Stepper, WillPopScope
  • Thème : ThemeData, colorScheme, TextTheme, AppBarTheme

Tous les contrôles sont stylisés automatiquement selon le theme et le colorScheme configurés.

CupertinoApp (iOS / Design Apple)

import 'package:flutter/cupertino.dart';

void main() {
runApp(const MyApp());
}

class MyApp extends StatelessWidget {
const MyApp({super.key});


Widget build(BuildContext context) {
return const CupertinoApp(
title: 'Cupertino App',
home: CupertinoHomeScreen(),
);
}
}

class CupertinoHomeScreen extends StatelessWidget {
const CupertinoHomeScreen({super.key});


Widget build(BuildContext context) {
return const CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text('Accueil'),
),
child: Center(
child: Text('Bouton iOS'),
),
);
}
}

Contrôles disponibles avec CupertinoApp

Widgets Cupertino (iOS Design) :

  • Layout : CupertinoPageScaffold, CupertinoTabScaffold, CupertinoSliverNavigationBar
  • Navigation : CupertinoNavigationBar, CupertinoTabBar, CupertinoSliverRefreshControl
  • Boutons : CupertinoButton, CupertinoButton.filled
  • Entrées : CupertinoTextField, CupertinoSlider, CupertinoSwitch, CupertinoSegmentedControl
  • Sélecteurs : CupertinoPicker, CupertinoDatePicker, CupertinoTimerPicker
  • Boîtes de dialogue : CupertinoAlertDialog, CupertinoActionSheetAction, showCupertinoDialog
  • Listes : CupertinoListTile, CupertinoListSection
  • Indicateurs : CupertinoActivityIndicator
  • Curseur : CupertinoScrollbar
  • Thème : CupertinoThemeData (simplifié comparé à Material)

Tous les contrôles respectent le style iOS (pas de Material Design).

2) Architecture adaptive (Material + Cupertino)

Si vous voulez une expérience Android et iOS différente, vous pouvez détecter la plateforme et retourner un MaterialApp ou un CupertinoApp.

import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';

void main() {
runApp(const MyApp());
}

class MyApp extends StatelessWidget {
const MyApp({super.key});


Widget build(BuildContext context) {
final isCupertino = defaultTargetPlatform == TargetPlatform.iOS;

if (isCupertino) {
return const CupertinoApp(
title: 'App iOS',
home: AdaptiveHomeScreen(),
);
}

return MaterialApp(
title: 'App Android',
theme: ThemeData(
useMaterial3: true,
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
),
home: const AdaptiveHomeScreen(),
);
}
}

class AdaptiveHomeScreen extends StatelessWidget {
const AdaptiveHomeScreen({super.key});


Widget build(BuildContext context) {
final isCupertino = defaultTargetPlatform == TargetPlatform.iOS;

if (isCupertino) {
return CupertinoPageScaffold(
navigationBar: const CupertinoNavigationBar(
middle: Text('Accueil iOS'),
),
child: Center(
child: CupertinoButton.filled(
onPressed: () {},
child: const Text('Bouton iOS'),
),
),
);
}

return Scaffold(
appBar: AppBar(title: const Text('Accueil Android')),
body: Center(
child: ElevatedButton(
onPressed: () {},
child: const Text('Bouton Material'),
),
),
);
}
}

3) Quand choisir quoi ?

CasOption recommandée
App multiplateforme simpleMaterialApp
App iOS natifCupertinoApp
UI 100% customWidgetsApp
App adaptative Android/iOSMaterialApp + CupertinoApp conditionnel

4) Bonnes pratiques

  1. Séparer la logique et l’UI pour faciliter l’adaptation
  2. Réutiliser le même modèle de données (même si l’UI change)
  3. Centraliser la navigation pour éviter les incohérences
  4. Adapter uniquement le rendu, pas toute l’app
  5. Tester sur les différentes plateformes